﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using INSTA.BankApplication.DAL;
using NUnit.Framework;
using System.Reflection;

namespace INSTA.BankApplication.DAL.Tests
{
    [TestFixture]
    public class Test_SqlServerSqlGenerator
    {
        private MockPerson              _person;
        private AbstractSqlGenerator    _generator;
        

        [SetUp]
        public void SetUp()
        {
            _person = MockPerson.GetTestPerson();
            _generator = _person.DbAccessor.SqlGenerator;
        }

        [Test]
        public void Test_Method_GenerateSqlFor_SELECT()
        {
            const string formatString = "SELECT * FROM [{0}] WHERE {1} = {2};";

            var expectedSql = string.Format(formatString,
                                            MockConstants.TABLE_NAME,
                                            MockConstants.FIELDNAME_ID,
                                            DataMapper.UNDEFINED_ID);

            Assert.AreEqual(expectedSql, _generator.GenerateSQLFor_Select());

        }

        [Test]
        public void Test_Method_GenerateSqlFor_DELETE()
        {
            const string formatString = "DELETE FROM [{0}] WHERE {1} = {2};";

            var expectedSql = string.Format(formatString,
                                            MockConstants.TABLE_NAME,
                                            MockConstants.FIELDNAME_ID,
                                            DataMapper.UNDEFINED_ID);

            Assert.AreEqual(expectedSql, _generator.GenerateSQLFor_Delete());

            //Console.WriteLine("Expected : " + _generator.GenerateSQLFor_Delete());
            //Console.WriteLine("Actual   : " + expectedSql);

        }


        [Test]
        public void Test_Method_GenerateSqlFor_INSERT()
        {
            const string formatString = "INSERT INTO [{0}] ({1}, {2}, {3}) VALUES ({4}, {5}, {6});";

            var expectedSql = string.Format(formatString,
                                            MockConstants.TABLE_NAME,
                                            MockConstants.FIELDNAME_NAME,
                                            MockConstants.FIELDNAME_FIRST_NAME,
                                            MockConstants.FIELDNAME_YEAR_OF_BIRTH,

                                            _generator.FormatParameter(MockConstants.DUMMY_NAME),
                                            _generator.FormatParameter(MockConstants.DUMMY_FIRST_NAME),
                                            _generator.FormatParameter(MockConstants.DUMMY_YEAR_OF_BIRTH));
                                           

            Assert.AreEqual(expectedSql, _generator.GenerateSQLFor_Insert());

        }


        [Test]
        public void Test_Method_GenerateSqlFor_UPDATE()
        {
            const string formatString = "UPDATE [{0}] SET {1} = {2}, {3} = {4}, {5} = {6} WHERE {7} = {8};";

            var expectedSql = string.Format(formatString,
                                            MockConstants.TABLE_NAME,
                                            MockConstants.FIELDNAME_NAME,
                                            _generator.FormatParameter(MockConstants.DUMMY_NAME),
                                            MockConstants.FIELDNAME_FIRST_NAME,
                                            _generator.FormatParameter(MockConstants.DUMMY_FIRST_NAME),
                                            MockConstants.FIELDNAME_YEAR_OF_BIRTH,
                                            _generator.FormatParameter(MockConstants.DUMMY_YEAR_OF_BIRTH),
                                            MockConstants.FIELDNAME_ID,
                                            _generator.FormatParameter(DataMapper.UNDEFINED_ID));
                                            

            Assert.AreEqual(expectedSql, _generator.GenerateSQLFor_Update());


        }


        [Test]
        public void Test_Method_GetPrimaryKeyPropertyName_WithMockPerson()
        {
            var expected = MockConstants.PROPERTYNAME_ID;

            Assert.AreEqual(expected, _generator.GetPrimaryKeyPropertyName());
        }
        

        [Test]
        public void Test_Method_GetPrimaryKeyPropertyName_WithBadMockPerson()
        {
            var badPerson = BadMockPerson.GetTestPerson();
            var generator = badPerson.DbAccessor.SqlGenerator;

            Assert.Throws<DuplicatePrimaryKeyException>(() => generator.GetPrimaryKeyPropertyName());
        }

        //[Test]
        //public void Test_Method_GetTableName_WithBadMockPerson()
        //{
        //    var badPerson = BadMockPerson.GetTestPerson2();
        //    var generator = badPerson.DbAccessor.SqlGenerator;

        //    Assert.Throws<MissingTableAttributeException>(() => generator.GetTableName());
        //}


        [Test]
        public void Test_Method_GetTableName()
        {
            var expected = MockConstants.TABLE_NAME;

            Assert.AreEqual(expected, _generator.GetTableName());
        }

        [Test]
        public void Test_Method_FormatParameter_ForString()
        {
            var expected = "'aa'";

            Assert.AreEqual(expected, _generator.FormatParameter("aa"));
        }


        [Test]
        public void Test_Method_FormatParameter_ForDateTime()
        {
            var date = new DateTime(2000, 1, 1);
            var expected = string.Format("#{0}#", date);

            Assert.AreEqual(expected, _generator.FormatParameter(date));

            
        }





    }
}
